import java.io.*;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.xml.sax.*;
import org.w3c.dom.*;

import java.io.File;
import org.w3c.dom.Document;
import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException; 

public class EconJM {
	
  public static void main(String[] args) throws Exception {
    /*
     *  fix for
     *    Exception in thread "main" javax.net.ssl.SSLHandshakeException:
     *       sun.security.validator.ValidatorException:
     *           PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
     *               unable to find valid certification path to requested target
     */
    TrustManager[] trustAllCerts = new TrustManager[] {
       new X509TrustManager() {
          public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
          }

          public void checkClientTrusted(X509Certificate[] certs, String authType) {  }

          public void checkServerTrusted(X509Certificate[] certs, String authType) {  }

       }
    };

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    // Create all-trusting host name verifier
    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
          return true;
        }
    };
    // Install the all-trusting host verifier
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    /*
     * end of the fix
     */
    String urlString = "https://backend.econjobmarket.org/rest/zz_67/XML/Data";
    String username = "britta";
    String password = "4britta@ubc";
    Authenticator.setDefault(new MyAuthenticator(username, password));
    URL url = new URL(urlString);
    InputStream content = (InputStream) url.getContent();
    BufferedReader in = new BufferedReader(new InputStreamReader(content));
    
    // XMl content
    String line;
    String xml_str ="";
    while ((line = in.readLine()) != null) {
      // System.out.println(line);
    	xml_str = xml_str + line;
    }
    
    InputSource xml = new InputSource();
    xml.setCharacterStream(new StringReader(xml_str));
    
    xml_parser(xml, 6);

  }
  
  public static String getTextValue(String def, Element doc, String tag) {
	    String value = def;
	    NodeList nl;
	    nl = doc.getElementsByTagName(tag);
	    if (nl.getLength() > 0 && nl.item(0).hasChildNodes()) {
	        value = nl.item(0).getFirstChild().getNodeValue();
	    }
	    return value;
	}

  // parsing XML
  public static void xml_parser(InputSource input_xml, int num_of_fields){
	  
	  /* 1. Id
	   * 2. first name
	   * 3. last name
	   * 4.	University	
	   * 5. Application Date
	   * 6. Job Title
	   */
	  
	  try {
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse (input_xml);

            // normalize text representation
            doc.getDocumentElement ().normalize ();

            // List of all applicants information
            NodeList listOfApplicants = doc.getElementsByTagName("applicant");
            // number of applicants
            int totalApplicants = listOfApplicants.getLength();
            Object app_table[][] = new Object [num_of_fields][totalApplicants];
            
            for(int i=0; i<totalApplicants ; i++){
            	Node firstApplicantNode = listOfApplicants.item(i);
            	if(firstApplicantNode.getNodeType() == Node.ELEMENT_NODE){


                    Element firstApplicantElement = (Element)firstApplicantNode;

                    //------- ID
                    NodeList appIdList = firstApplicantElement.getElementsByTagName("aid");
                    Element appIdElement = (Element)appIdList.item(0);

                    NodeList textIDList = appIdElement.getChildNodes();

                    // Add it to the table
                    app_table[0][i] = ((Node)textIDList.item(0)).getNodeValue().trim();
                    
                    //------- First Name
                    NodeList firstNameList = firstApplicantElement.getElementsByTagName("fname");
                    Element firstNameElement = (Element)firstNameList.item(0);

                    NodeList textFNList = firstNameElement.getChildNodes();
                    
                    // Add it to the table
                    app_table[1][i] = ((Node)textFNList.item(0)).getNodeValue().trim();

                    //------- Last Name
                    NodeList lastNameList = firstApplicantElement.getElementsByTagName("lname");
                    Element lastNameElement = (Element)lastNameList.item(0);

                    NodeList textLNList = lastNameElement.getChildNodes();
                    
                    // Add it to the table
                    app_table[2][i] = ((Node)textLNList.item(0)).getNodeValue().trim();
                    
                    //------- Institute Name
                    NodeList instNameList = firstApplicantElement.getElementsByTagName("degreeinst");	
                    Element instNameElement = (Element)instNameList.item(0);
                    NodeList textINList = instNameElement.getChildNodes();
                    if((Node)textINList.item(0) == null){
                                // Add it to the table
                                app_table[3][i] = "";
                    }
                    else{
	                    // Add it to the table
	                    app_table[3][i] = ((Node)textINList.item(0)).getNodeValue().trim();	
                    }
                    
                    //--------- Application Date
                    NodeList appDateList = firstApplicantElement.getElementsByTagName("appdate");
                    Element appDateElement = (Element)appDateList.item(0);

                    NodeList textADList = appDateElement.getChildNodes();
                    
                    // Add it to the table
                    app_table[4][i] = ((Node)textADList.item(0)).getNodeValue().trim();
                    
                    //---- Job Title
                    NodeList appJobTitleList = firstApplicantElement.getElementsByTagName("adtitle");
                    Element appJobTitleElement = (Element)appJobTitleList.item(0);

                    NodeList textAJTList = appJobTitleElement.getChildNodes();
                    
                    // Add it to the table
                    app_table[5][i] = ((Node)textAJTList.item(0)).getNodeValue().trim();

                    //------

                }//end of if clause


            }//end of for loop with i var
            
            // create a table of content based on values in the input dictionary
      	  	StringBuilder html = new StringBuilder("<table border='1'>");

      	  	// Id	first name	last name	University	Application Date	Job Title
      	  	html.append("<tr>");	
      	  	html.append("<th>" + "Id" + "</th>");
      	  	html.append("<th>" + "First Name" + "</th>");
      	  	html.append("<th>" + "Last Name" + "</th>");
      	  	html.append("<th>" + "University" + "</th>");
      	  	html.append("<th>" + "Application Date" + "</th>");
      	  	html.append("<th>" + "Job Title" + "</th>");
      	  	html.append("</tr>");
	      
      	  	for(int i = 0; i < app_table[0].length; i++){
				html.append("<tr>");
				for(int j = 0; j < app_table.length; j++){
					html.append("<td>" + app_table[j][i].toString() + "</td>");
				}
				html.append("</tr>");
      	  	}
			html.append("</table>");
			
			// System.out.println(html.toString());
			PrintWriter writer = new PrintWriter("ECONJBIndex.html", "UTF-8");
			writer.println(html.toString());
			writer.close();
			
      }catch (SAXParseException err) {
      System.out.println ("** Parsing error" + ", line " 
           + err.getLineNumber () + ", uri " + err.getSystemId ());
      System.out.println(" " + err.getMessage ());

      }catch (SAXException e) {
      Exception x = e.getException ();
      ((x == null) ? e : x).printStackTrace ();

      }catch (Throwable t) {
      t.printStackTrace ();
      }
      //System.exit (0);
  }//end of function
  
  static class MyAuthenticator extends Authenticator {
	    private String username, password;

	    public MyAuthenticator(String user, String pass) {
	      username = user;
	      password = pass;
	    }

	    protected PasswordAuthentication getPasswordAuthentication() {
	      System.out.println("Requesting Host  : " + getRequestingHost());
	      System.out.println("Requesting Port  : " + getRequestingPort());
	      System.out.println("Requesting Prompt : " + getRequestingPrompt());
	      System.out.println("Requesting Protocol: "
	          + getRequestingProtocol());
	      System.out.println("Requesting Scheme : " + getRequestingScheme());
	      System.out.println("Requesting Site  : " + getRequestingSite());
	      return new PasswordAuthentication(username, password.toCharArray());
	    }
	  }
}